﻿<!doctype html>
<html>

<head>
  <!-- 基础页面设置 -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
  <title>地图显示</title>
  <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
  <style>
    /* 基础容器样式 */
    html,
    body,
    #container {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    /* 清除标记按钮样式 */
    #clearMarkersButton {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 1000;
      background-color: #fff;
      border: 1px solid #ccc;
      padding: 10px;
      cursor: pointer;
    }

    /* 经纬度显示标签样式 */
    #coordinatesLabel {
      position: absolute;
      bottom: 15px;
      right: 15px;
      z-index: 1000;
      background-color: #fff;
      border: 1px solid #ccc;
      padding: 10px;
      font-size: 14px;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    /* 工具卡片样式 */
    .input-card {
      width: 150px;
      top: 10px;
      left: 10px;
      bottom: auto;
      position: absolute;
      z-index: 1000;
      background-color: #fff;
      border: 1px solid #ccc;
      padding: 10px;
    }

    /* 无人机数量显示标签样式 */
    #droneCountLabel {
      position: absolute;
      top: 50px;
      right: 15px;
      z-index: 1000;
      background-color: #fff;
      border: 1px solid #ccc;
      padding: 10px;
      font-size: 14px;
    }

    /* 自动跟踪状态显示样式 */
    #autoTrackStatus {
      position: absolute;
      top: 10px;
      right: 120px;
      z-index: 1000;
      background-color: #4CAF50;
      color: white;
      border: 1px solid #ccc;
      padding: 10px;
      font-size: 14px;
    }

    /* Canvas性能优化 - 添加willReadFrequently支持 */
    canvas {
      will-change: transform;
    }
  </style>
</head>

<body>
  <!-- 主要容器和控制元素 -->
  <div id="container"></div>
  <button id="clearMarkersButton">清除红点</button>
  <div id="autoTrackStatus">自动跟踪无人机</div>
  <div id="coordinatesLabel">纬度: - , 经度: -</div>
  <div id="droneCountLabel">当前无人机数量: 0</div>

  <!-- 地图控制工具卡片 -->
  <div class='input-card'>
    <div class="input-item">
      <input type="checkbox" onclick="toggleScale(this)" />比例尺
    </div>
    <div class="input-item">
      <input type="checkbox" id="toolbar" onclick="toggleToolBar(this)" />工具条
    </div>
    <div class="input-item">
      <input type="checkbox" id="controlBar" onclick="toggleControlBar(this)" />工具条方向盘
    </div>
    <div class="input-item">
      <input type="checkbox" id="overview" checked onclick="toggleOverViewShow(this)" />显示鹰眼
    </div>
  </div>

  <!-- 地图API和WebChannel脚本 -->
  <script
    src="https://webapi.amap.com/maps?v=2.0&key=da6f3fbf89b6eb5261f67d858c640547&plugin=AMap.Scale,AMap.HawkEye,AMap.ToolBar,AMap.ControlBar,AMap.MoveAnimation"></script>
  <!-- 引入Qt WebChannel通信库,该文件位于Qt安装目录下的qtwebchannel文件夹中 -->
  <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
  <script>
    // 初始化地图对象
    var map = new AMap.Map('container', {
      viewMode: '2D',
      zoom: 11,
      center: [104.38, 30.2905]
    });

    // 初始化地图控件
    var scale = new AMap.Scale({ visible: false });
    var toolBar = new AMap.ToolBar({
      visible: false,
      position: { top: '110px', right: '40px' }
    });
    var controlBar = new AMap.ControlBar({
      visible: false,
      position: { bottom: '50px', left: '10px' }
    });
    var overView = new AMap.HawkEye({ visible: true });

    // 添加地图控件
    map.addControl(scale);
    map.addControl(toolBar);
    map.addControl(controlBar);
    map.addControl(overView);

    // 地图控件显示切换函数
    function toggleScale(checkbox) {
      checkbox.checked ? scale.show() : scale.hide();
    }

    function toggleToolBar(checkbox) {
      checkbox.checked ? toolBar.show() : toolBar.hide();
    }

    function toggleControlBar(checkbox) {
      checkbox.checked ? controlBar.show() : controlBar.hide();
    }

    function toggleOverViewShow(checkbox) {
      checkbox.checked ? overView.show() : overView.hide();
    }

    // 全局变量定义
    var lng = [];                    // 经度数组
    var lat = [];                    // 纬度数组
    var circleMarkers = [];          // 圆形标记数组
    var polylines = [];              // 线段数组
    var lastDronePosition = null;    // 上一次无人机位置
    var droneMarkers = {};           // 无人机标记对象
    var isFirstUpdate = true;        // 是否首次更新标志
    var formationMarkers = {};       // 编队标记对象
    var lastMapUpdateTime = 0;       // 上次地图更新时间
    var minUpdateInterval = 300;     // 最小更新间隔（毫秒）
    var trackLeader = false;         // 是否跟踪模拟1号机
    var coordinatesLabel = document.getElementById('coordinatesLabel');

    // 检查qt对象是否存在，如果不存在则创建模拟对象
    if (typeof qt === 'undefined') {
      window.qt = {
        webChannelTransport: {
          send: function () { },
          onmessage: null
        }
      };
      console.log('创建了模拟的qt对象');
    }

    // 建立Qt WebChannel连接
    new QWebChannel(qt.webChannelTransport, function (channel) {
      window.bridge = channel.objects.bridge;
    });

    // 更新无人机数量显示
    function updateDroneCount() {
      // 计算真实的无人机数量（无人机标记 + 模拟无人机）
      var realDroneCount = Object.keys(droneMarkers).length + Object.keys(formationMarkers).length;
      document.getElementById("droneCountLabel").innerText = "当前无人机数量: " + realDroneCount;
    }

    // 添加一个新函数，用于聚焦到模拟1号机
    function focusOnLeaderDrone() {
      if (formationMarkers[1]) {
        var leaderPos = formationMarkers[1].getPosition();
        map.setCenter(leaderPos);
        // 设置一个适当的缩放级别
        map.setZoom(16);

        // 更新状态显示
        document.getElementById('autoTrackStatus').innerHTML = "已聚焦到模拟1号机";
        document.getElementById('autoTrackStatus').style.backgroundColor = "#FF5722";

        // 启用始终跟踪模拟1号机的模式
        enableLeaderTracking();
      } else {
        console.log("模拟1号机不存在，无法聚焦");
      }
    }

    // 启用跟踪模拟1号机的模式
    function enableLeaderTracking() {
      trackLeader = true;
    }

    // 禁用跟踪模拟1号机的模式
    function disableLeaderTracking() {
      trackLeader = false;
      document.getElementById('autoTrackStatus').innerHTML = "自动跟踪无人机";
      document.getElementById('autoTrackStatus').style.backgroundColor = "#4CAF50";
    }

    // 地图点击事件：记录点击位置的经纬度，并在地图上添加红色圆点
    map.on('click', function (e) {
      var latClicked = e.lnglat.getLat();
      var lngClicked = e.lnglat.getLng();
      lat.push(latClicked);
      lng.push(lngClicked);

      var circle = new AMap.CircleMarker({
        center: [lngClicked, latClicked],
        radius: 5,
        strokeColor: "#F33",
        strokeWeight: 2,
        strokeOpacity: 1,
        fillColor: "#ee2200",
        fillOpacity: 0.35
      });
      map.add(circle);
      circleMarkers.push(circle);

      if (circleMarkers.length > 1) {
        var j = lat.length - 2;
        var i = lat.length - 1;
        var path = [
          [lng[j], lat[j]],
          [lng[i], lat[i]]
        ];

        var polyline = new AMap.Polyline({
          path: path,
          strokeColor: "blue",
          strokeWeight: 3,
          strokeOpacity: 1
        });
        map.add(polyline);
        polylines.push(polyline);
      }

      if (window.bridge) {
        window.bridge.sendCoordinates(latClicked, lngClicked);
      }
    });

    // 计算所有无人机的中心点
    function calculateDroneCenter() {
      var positions = [];

      // 收集所有模拟无人机的位置
      for (var id in formationMarkers) {
        var pos = formationMarkers[id].getPosition();
        positions.push([pos.getLng(), pos.getLat()]);
      }

      // 收集所有实际无人机的位置
      for (var id in droneMarkers) {
        var pos = droneMarkers[id].getPosition();
        positions.push([pos.getLng(), pos.getLat()]);
      }

      // 如果没有无人机，返回地图当前中心
      if (positions.length === 0) {
        return map.getCenter();
      }

      // 计算平均位置
      var sumLng = 0, sumLat = 0;
      for (var i = 0; i < positions.length; i++) {
        sumLng += positions[i][0];
        sumLat += positions[i][1];
      }

      return new AMap.LngLat(sumLng / positions.length, sumLat / positions.length);
    }

    // 自动调整地图以容纳所有无人机
    function fitAllDronesToView() {
      var positions = [];

      // 收集所有模拟无人机的位置
      for (var id in formationMarkers) {
        var pos = formationMarkers[id].getPosition();
        positions.push([pos.getLng(), pos.getLat()]);
      }

      // 收集所有实际无人机的位置
      for (var id in droneMarkers) {
        var pos = droneMarkers[id].getPosition();
        positions.push([pos.getLng(), pos.getLat()]);
      }

      // 如果没有无人机，不执行操作
      if (positions.length === 0) {
        return;
      }

      // 创建边界对象
      var bounds = new AMap.Bounds();

      // 扩展边界以包含所有无人机
      for (var i = 0; i < positions.length; i++) {
        bounds.extend(new AMap.LngLat(positions[i][0], positions[i][1]));
      }

      // 扩展视图边界，添加20%的边距
      var southWest = bounds.getSouthWest();
      var northEast = bounds.getNorthEast();
      var width = northEast.getLng() - southWest.getLng();
      var height = northEast.getLat() - southWest.getLat();

      var padding = Math.max(width, height) * 0.2;  // 20% 的边距

      bounds = new AMap.Bounds(
        new AMap.LngLat(southWest.getLng() - padding, southWest.getLat() - padding),
        new AMap.LngLat(northEast.getLng() + padding, northEast.getLat() + padding)
      );

      // 使地图适应新的边界
      map.setBounds(bounds);
    }

    // 自动定位到无人机区域（使用节流控制）
    function autoFocusOnDrones() {
      // 获取当前时间
      var now = Date.now();

      // 如果距离上次更新地图没有超过最小间隔，则不更新
      if (now - lastMapUpdateTime < minUpdateInterval) {
        return;
      }

      // 记录当前时间为最后更新时间
      lastMapUpdateTime = now;

      // 如果启用了跟踪模拟1号机的模式，并且模拟1号机存在
      if (trackLeader && formationMarkers[1]) {
        var leaderPos = formationMarkers[1].getPosition();
        map.setCenter(leaderPos);
        return;
      }

      // 一架无人机时：简单地将其居中显示
      if (Object.keys(formationMarkers).length + Object.keys(droneMarkers).length === 1) {
        var center = calculateDroneCenter();
        map.setCenter(center);
      }
      // 多架无人机时：自动适配所有无人机到视图
      else if (Object.keys(formationMarkers).length + Object.keys(droneMarkers).length > 1) {
        fitAllDronesToView();
      }
    }

    // 更新无人机位置在地图显示，添加高度信息
    function updateDronePosition(lat, lng, droneId, altitude) {
      // 如果未提供高度信息，设置为默认值
      if (altitude === undefined) {
        altitude = 0;
      }

      if (isFirstUpdate) {
        map.setCenter([lng, lat]);
        isFirstUpdate = false;
      }

      // 构建飞行轨迹线
      if (lastDronePosition) {
        var path = [
          [lastDronePosition.lng, lastDronePosition.lat],
          [lng, lat]
        ];

        var dronePolyline = new AMap.Polyline({
          path: path,
          strokeColor: "black",
          strokeWeight: 3,
          strokeOpacity: 1
        });
        map.add(dronePolyline);
        polylines.push(dronePolyline);
      }

      // 创建或更新无人机标记
      if (!droneMarkers[droneId]) {
        // 创建新的无人机标记
        droneMarkers[droneId] = new AMap.Marker({
          position: [lng, lat],
          label: {
            content: "无人机 " + droneId + " 高度: " + altitude + "m",
            offset: new AMap.Pixel(20, 20),
            color: '#FF0000'   // 字体颜色，这里设置为红色
          },
          icon: new AMap.Icon({
            size: new AMap.Size(32, 32),
            image: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
            imageSize: new AMap.Size(32, 32)
          })
        });
        map.add(droneMarkers[droneId]);

        // 更新无人机数量显示
        updateDroneCount();
      } else {
        // 更新现有无人机标记位置和标签
        droneMarkers[droneId].setPosition([lng, lat]);
        droneMarkers[droneId].setLabel({
          content: "无人机 " + droneId + " 高度: " + altitude + "m",
          offset: new AMap.Pixel(20, 20),
          color: '#FF0000'
        });
      }

      // 更新上一次位置记录
      lastDronePosition = { lat: lat, lng: lng };
      if (lastDronePosition[droneId]) {
        lastDronePosition[droneId] = { lat: lat, lng: lng };
      } else {
        lastDronePosition[droneId] = { lat: lat, lng: lng };
      }

      // 自动定位到无人机区域
      autoFocusOnDrones();
    }

    // 更新无人机位置并生成静止标记，添加高度信息
    function updateDronePositionWithFormation(droneId, lat, lng, altitude) {
      // 如果未提供高度信息，设置为默认值
      if (altitude === undefined) {
        altitude = 0;
      }

      var targetPos = new AMap.LngLat(lng, lat);

      if (formationMarkers[droneId]) {
        // 如果标记存在，手动实现动画效果
        var marker = formationMarkers[droneId];
        var currentPos = marker.getPosition();

        // 使用 setTimeout 模拟动画移动
        var steps = 50; // 动画的步数
        var stepDuration = 20; // 每步持续时间，毫秒
        var latStep = (lat - currentPos.getLat()) / steps;
        var lngStep = (lng - currentPos.getLng()) / steps;

        var step = 0;
        function animate() {
          if (step >= steps) {
            // 动画结束时更新标签中的高度信息
            marker.setLabel({
              content: "模拟 " + droneId + " 高度: " + altitude + "m",
              offset: new AMap.Pixel(10, 10),
              style: {
                color: '#FF0000'
              }
            });

            // 如果是模拟1号机且跟踪模式开启，确保它在中心
            if (droneId == 1 && trackLeader) {
              map.setCenter(new AMap.LngLat(lng, lat));
            }

            return;
          }
          var newLat = currentPos.getLat() + latStep * step;
          var newLng = currentPos.getLng() + lngStep * step;
          marker.setPosition(new AMap.LngLat(newLng, newLat));

          // 在动画过程中，如果是1号机并且跟踪模式开启，实时更新地图中心
          if (droneId == 1 && trackLeader) {
            map.setCenter(new AMap.LngLat(newLng, newLat));
          }

          step++;
          setTimeout(animate, stepDuration);
        }
        animate();
      } else {
        // 如果标记不存在，直接创建
        var marker = new AMap.Marker({
          position: targetPos,
          label: {
            content: "模拟 " + droneId + " 高度: " + altitude + "m",
            offset: new AMap.Pixel(10, 10),
            // 添加以下样式属性
            style: {
              fontSize: '14px',  // 修改为更合理的字体大小
              color: '#FF0000'   // 字体颜色，这里设置为红色
            }
          },
          icon: new AMap.Icon({
            size: new AMap.Size(32, 32),
            image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
            imageSize: new AMap.Size(32, 32)
          })
        });
        map.add(marker);
        formationMarkers[droneId] = marker;

        // 更新无人机数量显示
        updateDroneCount();

        // 如果是模拟1号机且跟踪模式开启，立即更新地图中心
        if (droneId == 1 && trackLeader) {
          map.setCenter(targetPos);
        }
      }

      // 如果是模拟1号机且跟踪模式开启，优先更新地图中心
      if (droneId == 1 && trackLeader) {
        map.setCenter(targetPos);
      } else {
        // 其他无人机使用常规的自动定位
        autoFocusOnDrones();
      }
    }

    // 鼠标移动事件：实时显示当前经纬度
    map.on('mousemove', function (e) {
      var latHover = e.lnglat.getLat();
      var lngHover = e.lnglat.getLng();
      coordinatesLabel.innerHTML = "纬度: " + latHover.toFixed(6) + ", 经度: " + lngHover.toFixed(6);
    });

    // 清除标记和轨迹线的按钮事件
    document.getElementById('clearMarkersButton').addEventListener('click', function () {
      // 清除红点标记
      for (var i = 0; i < circleMarkers.length; i++) {
        map.remove(circleMarkers[i]);
      }
      circleMarkers = [];

      // 清除轨迹线
      for (var i = 0; i < polylines.length; i++) {
        map.remove(polylines[i]);
      }
      polylines = [];
      lat = [];
      lng = [];
      lastDronePosition = null;

      // 清除所有无人机标记
      for (var droneId in droneMarkers) {
        map.remove(droneMarkers[droneId]);
        delete droneMarkers[droneId];
      }

      // 清除所有模拟无人机标记
      for (var droneId in formationMarkers) {
        map.remove(formationMarkers[droneId]);
        delete formationMarkers[droneId];
      }

      // 更新无人机数量显示
      updateDroneCount();

      // 禁用跟踪模拟1号机的模式
      disableLeaderTracking();
    });
    // 在地图初始化后添加Canvas优化
    map.on('complete', function () {
      // 查找所有canvas元素并添加willReadFrequently属性
      var canvases = document.querySelectorAll('canvas');
      canvases.forEach(function (canvas) {
        var ctx = canvas.getContext('2d');
        if (ctx && typeof ctx.getContextAttributes === 'function') {
          // 尝试设置willReadFrequently
          try {
            canvas.getContext('2d', { willReadFrequently: true });
          } catch (e) {
            console.log('无法设置willReadFrequently属性');
          }
        }
      });
    });

    // 改进qt对象检查
    if (typeof qt === 'undefined') {
      window.qt = {
        webChannelTransport: {
          send: function (data) {
            console.log('模拟WebChannel发送:', data);
          },
          onmessage: null
        }
      };
      console.log('创建了模拟的qt对象');
    }
  </script>
</body>

</html>